package com.hui.auth.config.shiro.filter;

import com.hui.auth.config.shiro.SecurityUtil;
import com.hui.auth.dto.JsonResult;
import com.hui.auth.entity.AuthPermission;
import com.hui.auth.entity.AuthRole;
import com.hui.auth.entity.AuthUser;
import com.hui.auth.exception.AuthError;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 权限拦截器
 *
 * @apiNote 两个方法同时返回false才不会通过
 */
@Component
public class PermissionFilter extends AccessControlFilter {

    /**
     * 校验规则
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        Subject subject = getSubject(request, response);
        AuthUser user = (AuthUser) subject.getSession().getAttribute(SecurityUtil.USER_KEY);
        if (null == user) {
            return true;
        }

        HttpServletRequest httpRequest = ((HttpServletRequest) request);
        if (httpRequest.getMethod().equals("OPTIONS")) {
            return true;
        }
        if (this.isLoginRequest(request, response)) {
            return true;
        }
//        String uri = httpRequest.getRequestURI();//获取URI
        String uri = ((ShiroHttpServletRequest) request).getServletPath();
        String basePath = httpRequest.getContextPath();//获取basePath
        if (null != uri && uri.startsWith(basePath)) {
            uri = uri.replaceFirst(basePath, "");
        }
        List<AuthPermission> perms = user.getPermissions();
        if (subject.hasRole("系统管理员")) {
            return true;
        }
        return isPermitted(perms, uri);
    }

    private boolean isPermitted(List<AuthPermission> perms, String uri) {
        if (null != perms) {
            for (AuthPermission p : perms) {
                String uriInDB = p.getUrl();
                if (uri.contains(uriInDB)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 校验不通过后的处理
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        Subject subject = getSubject(request, response);
        if (null == subject.getPrincipal()) {//表示没有登录，重定向到登录页面
            redirectToLogin(request, response);
        } else {//没有权限处理
            JsonResult jsonResult = new JsonResult();
            jsonResult.setCode(AuthError.NO_PERMISSION.code);
            jsonResult.setMsg(AuthError.NO_PERMISSION.msg);
            HttpServletRequest httpRequest = ((HttpServletRequest) request);
            HttpServletResponse httpResponse = ((HttpServletResponse) response);
            CrosUtil.crosOrgin(httpRequest, httpResponse);
            response.getWriter().write(jsonResult.toString());
        }
        return false;
    }

}
